/*
Package KcpServer
author: jamon
time: 2023-09-05
desc:
*/
package KcpServer

import (
	"github.com/xtaci/kcp-go"
	"net"
)

// Server 增加这个封装的主要目的是: 在不关闭Socket的情况下, 关掉Listener以停止接收新的会话,
// 已建立的会话依然能够正常通信, 从而可以实现优雅关闭.
type Server struct {
	rawConn     net.PacketConn
	kcpListener *kcp.Listener
}

func Listen(addr string) (s *Server, e error) {
	rawConn, e := net.ListenPacket("udp", addr)
	if e != nil {
		return
	}

	// 不使用FEC前向纠错，因为FEC会增加额外的延迟
	listener, e := kcp.ServeConn(
		nil,
		0,
		0,
		rawConn,
	)
	s = &Server{
		rawConn:     rawConn,
		kcpListener: listener,
	}
	return
}

func (s *Server) Accept() (net.Conn, error) {
	return s.kcpListener.Accept()
}

func (s *Server) StopAccept() error {
	return s.kcpListener.Close()
}

func (s *Server) Close() error {
	_ = s.StopAccept()
	return s.rawConn.Close()
}
